Cコンパイラ作成入門 メモ
環境
div/9ccで以下を実行しディレクトリ移動すればいける
$ docker run -v "$PWD"/.:/home --rm -ti alpine:exec-c
# cd home
実行
$ makeして$ ./9cc 'hoge'とか
通常のやり方
$ gcc -o 9cc 9cc.c
$ ./9cc 123 > tmp.sして、$ cat tmp.sなどとすると出力したアセンブリが見れる
このアセンブリは$ gcc -o tmp tmp.sとすることで機械語に翻訳し$ ./tmpで実行できる
今の場合では何も出力されないので$ echo $?で演算結果を確認できる
テストを実行
通常のやり方
$ ./test.sh
テストスクリプトのデバッグ
$ bash -s test.sh
makeコマンド
実行されるとカレントディレクトリの「Makefile」を実行する
参考
あとまわし
**argv
stderr
strtol
数値を読み込んだあと、第二引数のポインタをアップデートして、読み込んだ最後の文字の次の文字を指すように値を更新する
%ld
continue (in while)
fprintf
他の人の
目次
はじめに
本書の想定する開発環境
本書の表記法
変更履歴
機械語とアセンブラ
CPUとメモリ
アセンブラとは
Cとそれに対応するアセンブラ
簡単な例
関数呼び出しを含む例
本章のまとめ
ステップ1:整数1個をコンパイルする言語の作成
コンパイラ本体の作成
ユニットテストの作成
makeによるビルド
gitによるバージョン管理
ステップ2:加減算のできるコンパイラの作成
ステップ3:トークナイザを導入
文法の記述方法と再帰下降構文解析
文脈自由文法
生成規則による演算子の優先順位の表現
間接的な再帰を含む生成規則
演算子の結合規則
抽象構文木
再帰下降構文解析
スタックマシン
スタックマシンの概念
スタックマシンへのコンパイル
x86-64におけるスタックマシンの実現方法
ステップ4:四則演算のできる言語の作成
ステップ5:任意長の入力のサポート
可変長ベクタ
データ構造のユニットテスト
ベクタを使う
ステップ6:1文字のローカル変数
スタック上の変数領域
トークナイザの変更
パーサの変更
左辺値と右辺値
任意のアドレスから値をロードする方法
コードジェネレータの変更
メイン関数の変更
ステップ7:複数文字のローカル変数
マップ
複数文字のローカル変数をサポート
分割コンパイルとリンク
リンク
何をヘッダファイルに書けばよいのか
Makefileの変更
ステップ8: ==と!=を追加する
1972年のCコンパイラ
ステップ9: 関数の呼び出しに対応する
ステップ10: 関数の定義に対応する
ステップ11: 制御構文を足す
ステップ12: 暗黙の変数定義を廃止して、intというキーワードを導入する
ステップ13: ポインタ型を導入する
ポインタを表す型を定義する
ポインタが指している値に代入する
ステップ14: ポインタの加算と減算を実装する
ステップ15: 配列を実装する
配列型を定義する
配列からポインタへの暗黙の型変換を実装する
ステップ16: 配列の添字を実装する
ステップ17: グローバル変数を実装する
ステップ18: 文字型を実装する
ステップ19: 文字列リテラルを実装する
ステップ20: テストをCで書き直す
ステップ21以降: [要加筆
付録:x86-64命令セット チートシート
整数レジスタの一覧
メモリアクセス
関数呼び出し
条件分岐
条件代入
整数・論理演算
付録:Gitによるバージョン管理
コミットするときの注意点
Gitの内部構造
付録:参考資料
Rustで
保留
Args型
例外処理
Dockerの環境構築
Dockerfile
code:Dockerfile
FROM rust:1.31
WORKDIR /usr/src/r9cc
COPY . .
RUN cargo install --path .
$ docker build -t r9cc .
$ docker run -v "$PWD"/.:/usr/src/9rcc -it --rm --name r9cc r9cc
この辺参考になるかも
目次
はじめに
本書の想定する開発環境
本書の表記法
変更履歴
機械語とアセンブラ
CPUとメモリ
アセンブラとは
Cとそれに対応するアセンブラ
簡単な例
関数呼び出しを含む例
本章のまとめ
ステップ1:整数1個をコンパイルする言語の作成
コンパイラ本体の作成
ユニットテストの作成
makeによるビルド
gitによるバージョン管理
ステップ2:加減算のできるコンパイラの作成